﻿#region Imports
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using CommonUtilities.Extensions;
#endregion

namespace CommonUtilities.Util
{
    /// <summary>
    /// http://stackoverflow.com/questions/491595/best-way-to-parse-command-line-arguments-in-c
    /// http://www.codeproject.com/Articles/3111/C-NET-Command-Line-Arguments-Parser
    /// http://www.codeproject.com/Articles/63374/C-NET-Command-Line-Argument-Parser-Reloaded
    /// http://tirania.org/blog/archive/2008/Oct-14.html
    /// https://commandline.codeplex.com/
    /// 
    /// </summary>
    /// <seealso cref="http://msdn.microsoft.com/en-us/library/acy3edy3%28v=vs.100%29.aspx"/>
    /// <seealso cref="http://msdn.microsoft.com/en-us/library/cb20e19t%28v=vs.100%29.aspx"/>
    /// <seealso cref="http://msdn.microsoft.com/en-us/library/96s74eb0%28v=vs.100%29.aspx"/>
    /// <seealso cref=""/>
    public class CommandLineParser
    {
        private static Dictionary<string, string> commandLineArgs = new Dictionary<string, string>();
        public static Dictionary<string, string> CommandLineArgs
        {
            get
            {
                if (commandLineArgs.IsNull()) commandLineArgs = new Dictionary<string, string>();
                return commandLineArgs;
            }
            private set { commandLineArgs = value; }
        }

        protected enum enumParseState : int { StartToken, InQuote, InToken };

        public static Dictionary<string, string> GetCommandLineArgs(string[] args)
        {
            if (args.FirstOrDefault().StartsWith("-"))
            {
                for (int i = 0; i < args.Length / 2; i++)
                {
                    CommandLineArgs.AddToDictionary(args[2 * i], args[2 * i + 1]);
                }
            }
            else
            {
                for (int i = 0; i < args.GetCount(); i++)
                {
                    CommandLineArgs.AddToDictionary("Arg_" + (i + 1), args[i]);
                }
            }

            return CommandLineArgs;
        }

        public static List<string> ManuallyParseCommandLine()
        {
            String CommandLineArgs = Environment.CommandLine.ToString();

            Console.WriteLine("Command entered: " + CommandLineArgs);

            List<String> listArgs = new List<String>();

            Regex rWhiteSpace = new Regex("[\\s]");
            StringBuilder token = new StringBuilder();
            enumParseState eps = enumParseState.StartToken;

            for (int i = 0; i < CommandLineArgs.Length; i++)
            {
                char c = CommandLineArgs[i];
                //    Console.WriteLine(c.ToString()  + ", " + eps);
                //Looking for beginning of next token
                if (eps == enumParseState.StartToken)
                {
                    if (rWhiteSpace.IsMatch(c.ToString()))
                    {
                        //Skip whitespace
                    }
                    else if (c == '"')
                    {
                        eps = enumParseState.InQuote;
                    }
                    else
                    {
                        token.Append(c);
                        eps = enumParseState.InToken;
                    }
                }
                else if (eps == enumParseState.InToken)
                {
                    if (rWhiteSpace.IsMatch(c.ToString()))
                    {
                        Console.WriteLine("Token: [" + token.ToString() + "]");
                        listArgs.Add(token.ToString().Trim());
                        eps = enumParseState.StartToken;

                        //Start new token.
                        token.Remove(0, token.Length);
                    }
                    else if (c == '"')
                    {
                        // token.Append(c);
                        eps = enumParseState.InQuote;
                    }
                    else
                    {
                        token.Append(c);
                        eps = enumParseState.InToken;
                    }
                }
                //When in a quote, white space is included in the token
                else if (eps == enumParseState.InQuote)
                {
                    if (c == '"')
                    {
                        // token.Append(c);
                        eps = enumParseState.InToken;
                    }
                    else
                    {
                        token.Append(c);
                        eps = enumParseState.InQuote;
                    }
                }
            }

            if (token.ToString() != "")
            {
                listArgs.Add(token.ToString());
                Console.WriteLine("Final Token: " + token.ToString());
            }

            return listArgs;
        }

        public static void UpdateKillInfo(object sender, EventArgs e)
        {
            Messages.MessageBoxUtil.Show(true, "process exited");
        }

        public static void UpdateKillInfo()
        {
            System.Diagnostics.Process.GetProcesses()
                ._ForEach(proc => proc.Exited += UpdateKillInfo);
            //    ._ForEach(proc => proc.Exited += (sender, e) =>
            //    {
            //        Messages.MessageBoxUtil.Show(true, proc.Id + " :: " + proc.ProcessName, proc.ProcessName);
            //    });
        }
    }
}
